/*
* ErrorLogWriter class: XML error log writer
*
* Authors:		R. LOPES
* Contributors:	R. LOPES
* Created:		23 October 2002
* Modified:		24 October 2002
*
* Version:		1.0
*/

using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace GeocacheDownloader
{
    /// <summary>
    /// ErrorLogWriter class
    /// </summary>
    public class ErrorLogWriter : TextWriter
    {
        // Variables
        private bool disposed;

        public bool Disposed
        {
            get { return disposed; }
        }
        private XmlTextWriter Writer;

        // Constructor
        public ErrorLogWriter(string FilePath)
        {
            disposed = false;
            Writer = new XmlTextWriter(FilePath, Encoding.Unicode);

            // Write header
            Writer.Formatting = Formatting.Indented;
            Writer.WriteStartDocument();
            Writer.WriteStartElement("error");
            Writer.Flush();
        }

        // Destructor (equivalent to Finalize() without the need to call base.Finalize())
        ~ErrorLogWriter()
        {
            Dispose(false);
        }

        // Free resources immediately
        protected override void Dispose(bool Disposing)
        {
            if (!disposed)
            {
                if (Disposing)
                {
                }
                // Close file
                Writer.Close();
                Writer = null;
                // disposed
                disposed = true;
                // Parent disposing
                base.Dispose(Disposing);
            }
        }

        // Close the file
        public override void Close()
        {
            // Write footer
            Writer.WriteEndElement();
            Writer.WriteEndDocument();
            Writer.Flush();
            // Free resources
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        // Implement Encoding() method from TextWriter
        public override Encoding Encoding
        {
            get
            {
                return (Encoding.Unicode);
            }
        }

        // Implement WriteLine() method from TextWriter (remove MethodImpl attribute for single-threaded app)
        // Use stack trace and reflection to get the calling class and method
        [MethodImpl(MethodImplOptions.Synchronized)]
        public override void WriteLine(string Txt)
        {
            Writer.WriteStartElement("event");
            Writer.WriteStartElement("time");
            Writer.WriteString(DateTime.Now.ToLongTimeString());
            Writer.WriteEndElement();
            Writer.WriteStartElement("class");
            Writer.WriteString(new StackTrace().GetFrame(2).GetMethod().ReflectedType.FullName);
            Writer.WriteEndElement();
            Writer.WriteStartElement("method");
            Writer.WriteString(new StackTrace().GetFrame(2).GetMethod().Name);
            Writer.WriteEndElement();
            Writer.WriteStartElement("text");
            Writer.WriteString(Txt);
            Writer.WriteEndElement();
            Writer.WriteEndElement();
            Writer.Flush();
        }

        public void WriteLine(string text, string param)
        {
            Writer.WriteStartElement("event");
            Writer.WriteStartElement("time");
            Writer.WriteString(DateTime.Now.ToLongTimeString());
            Writer.WriteEndElement();
            Writer.WriteStartElement("class");
            Writer.WriteString(new StackTrace().GetFrame(2).GetMethod().ReflectedType.FullName);
            Writer.WriteEndElement();
            Writer.WriteStartElement("method");
            Writer.WriteString(new StackTrace().GetFrame(2).GetMethod().Name);
            Writer.WriteEndElement();
            Writer.WriteStartElement("text");
            Writer.WriteString(text);
            Writer.WriteEndElement();
            Writer.WriteStartElement("param");
            Writer.WriteString(param);
            Writer.WriteEndElement();
            Writer.WriteEndElement();
            Writer.Flush();
        }
    }
}
